feat(auth): migrate auth APIs to AmplifyContext - #14836
Conversation
- Add AmplifyContext overloads to all public auth APIs (signIn, signUp, signOut, getCurrentUser, fetchUserAttributes, confirmSignIn, etc.) - Public APIs use resolveCtxArgs with getGlobalContext() fallback - Server wrappers (server/getCurrentUser, server/fetchUserAttributes) take AmplifyContext explicitly — no global fallback - Internal signIn variants take (ctx, input) directly - Utilities (assertUserNotAuthenticated, dispatchSignedInHubEvent) accept ctx - Replace Amplify.getConfig() with ctx.resourcesConfig throughout - Replace AmplifyClassV6 with AmplifyContext in internal APIs - Add createMockAmplifyContext test utility - Update affected test files to use mock context
|
resolveCtxArgs generic constraint requires T extends unknown[]. undefined does not satisfy this - use empty tuple [] instead.
The fetchAuthSession helper from core/internals/utils expects AmplifyClass, not AmplifyContext. Use the context's own fetchAuthSession method directly.
Maintain backward compatibility with adapter-nextjs which still uses runWithAmplifyServerContext + ContextSpec pattern. Server wrappers now detect whether they received an AmplifyContext or ContextSpec and resolve accordingly.
- Remove unused Amplify imports from test files - Fix prettier formatting (line length, indentation)
Migrate test mocking from Amplify.getConfig() singleton to passing
mockCtx directly via createMockAmplifyContext(). This aligns tests
with the new resolveCtxArgs pattern where APIs accept an optional
AmplifyContext as their first argument.
- Remove jest.mock('@aws-amplify/core') in favor of direct ctx passing
- Replace fetchAuthSession singleton mock with ctx.fetchAuthSession
- Use customCtx for endpoint override tests
- Fix autoSignInUserConfirmed to match updated signUpHelpers routing
- Add Amplify.configure() for tests that reach getSignInResult (still
uses singleton internally)
| export const getCurrentUser = async ( | ||
| contextSpec: AmplifyServer.ContextSpec, | ||
| export const getCurrentUser = ( | ||
| ctxOrContextSpec: AmplifyContext | AmplifyServer.ContextSpec, |
There was a problem hiding this comment.
Nit / suggestion: This ctxOrContextSpec resolution is duplicated verbatim in both server/fetchUserAttributes.ts and server/getCurrentUser.ts. It'd make a nice small shared utility — something like:
// Resolves a server-side argument that may be either the new AmplifyContext
// or a legacy AmplifyServer.ContextSpec, into a concrete AmplifyContext.
export const resolveServerContext = (
ctxOrContextSpec: AmplifyContext | AmplifyServer.ContextSpec,
): AmplifyContext =>
'resourcesConfig' in ctxOrContextSpec
? ctxOrContextSpec
: getAmplifyServerContext(ctxOrContextSpec).amplify;Both call sites then become const ctx = resolveServerContext(ctxOrContextSpec);, and the duck-typing discriminator lives in one place if it ever needs to change.
There was a problem hiding this comment.
Done in 9b597bb. Extracted the duck-typing into a shared resolveServerContext helper at apis/server/resolveServerContext.ts:
export const resolveServerContext = (
ctxOrContextSpec: AmplifyContext | AmplifyServer.ContextSpec,
): AmplifyContext => {
const ctx =
'resourcesConfig' in ctxOrContextSpec
? ctxOrContextSpec
: getAmplifyServerContext(ctxOrContextSpec).amplify;
return ctx as AmplifyContext;
};Both server/getCurrentUser.ts and server/fetchUserAttributes.ts now just call const ctx = resolveServerContext(ctxOrContextSpec);, and the discriminator lives in one place. (Kept the cast inside the helper and dropped the now-redundant call-site casts.)
| signInInput?.options?.authFlowType === 'USER_AUTH' | ||
| ? await signInWithUserAuth(signInInput) | ||
| : await signIn(signInInput); | ||
| const output = await signIn(signInInput); |
There was a problem hiding this comment.
Can you please confirm if this change is intended**
This is the one change that isn't a mechanical context migration, and it looks like it may introduce a behavioral regression:
- const output =
- signInInput?.options?.authFlowType === 'USER_AUTH'
- ? await signInWithUserAuth(signInInput)
- : await signIn(signInInput);
+ const output = await signIn(signInInput);Two things suggest this drops the cached session during USER_AUTH auto sign-in:
- Routing through
signInis not equivalent to callingsignInWithUserAuthdirectly —signInfirst runsresetAutoSignIn(false)andassertUserNotAuthenticated(ctx). The original code deliberately bypassed those for theUSER_AUTHpath. Calling them mid-auto-sign-in can disturb the auto-sign-in state machine. - In
autoSignIn.test.ts, the assertion that the flow forwardssession: 'ASDFGHJKL'was silently removed:
expect(mockHandleUserAuthFlow).toHaveBeenCalledWith(
expect.objectContaining({
username: user1.username,
- session: 'ASDFGHJKL',
}),
);Dropping a coverage assertion to make a test pass is a red flag. Could you confirm whether the cached session is still threaded into the USER_AUTH flow after this change, or whether this is an unintended regression? If the behavior genuinely changed, it likely deserves its own PR + changelog note rather than an inline assertion deletion.
There was a problem hiding this comment.
Great catch — you were right, this was an unintended regression, now fixed in 9b597bb.
Confirmed the cause: routing USER_AUTH through signIn() runs resetAutoSignIn(false) first, which dispatches { type: 'RESET' } to autoSignInStore (the false only preserves the callback, not the store state). By the time signInWithUserAuth runs, its if (autoSignInStoreState.active …) guard is false, so the cached session is never forwarded to handleUserAuthFlow — auto-sign-in starts a fresh flow instead of resuming the primed session.
Restored the branch to call signInWithUserAuth directly (matching v7-poc behavior):
const output =
signInInput?.options?.authFlowType === 'USER_AUTH'
? await signInWithUserAuth(getGlobalContext(), signInInput)
: await signIn(signInInput);I used getGlobalContext() rather than threading ctx as a parameter because auto-sign-in is inherently client-side/post-configure (consistent with the other client-only flows like completeOAuthFlow and handleWebAuthnSignInResult in this split); the v7-poc ctx-threading can land later without a behavior change.
On the dropped assertion — you were right to flag it. I re-added session: 'ASDFGHJKL' in autoSignIn.test.ts, and I also found autoSignInUserConfirmed.test.ts had been changed to assert the regressed behavior (expecting signIn for USER_AUTH); I corrected it to assert signInWithUserAuth(mockCtx, input) is called and signIn is not. Both tests now pass with the fix (full auth suite green: 101/101 suites, 1144 tests).
| const mockReplaceState = jest.fn(); | ||
|
|
||
| beforeAll(() => { | ||
| setGlobalContext(createMockAmplifyContext()); |
There was a problem hiding this comment.
Question: Do we need to call clearGlobalContext() in afterAll here (and in the other test files that call setGlobalContext)?
It looks like only autoSignIn.test.ts cleans up the global context in afterAll. The other files that call setGlobalContext (this one, signInResumable.test.ts, signInWithCustomAuth.test.ts, etc.) leave it set after the suite finishes, which could leak state across files depending on how much module isolation Jest gives us. Should we standardize on a clearGlobalContext() in afterAll for all of them?
There was a problem hiding this comment.
Agreed — standardized in 9b597bb. Added clearGlobalContext() in afterAll to every suite that calls setGlobalContext (this file, signInResumable, signInWithSRP, signInWithCustomAuth, signInWithCustomSRPAuth, signInWithUserAuth, signInWithUserPassword).
While doing this I found the leak was actually being relied on: in signInWithUserPassword.test.ts the Cognito ASF describe had no context setup of its own and depended on the global context leaking from the sibling signIn API happy path cases describe. Adding cleanup exposed that, so I made Cognito ASF self-contained with its own beforeAll(setGlobalContext) / afterAll(clearGlobalContext).
| const ctx: AmplifyContext = { | ||
| resourcesConfig, | ||
| libraryOptions: {}, | ||
| fetchAuthSession: jest.fn().mockResolvedValue({}), |
There was a problem hiding this comment.
Suggestion: Could createMockAmplifyContext return the mock members already typed as jest.Mock?
Across the migrated tests, this 3-line incantation recurs ~28× (≈14 for mockCtx and ~14 for the per-test customCtx):
(mockCtx.fetchAuthSession as jest.Mock).mockResolvedValue({
tokens: { accessToken: decodeJWT(mockAccessToken) },
});The as jest.Mock cast (28×) exists only because the util types these fields as AmplifyContext['fetchAuthSession'] rather than jest.Mock. If createMockAmplifyContext returned a type where fetchAuthSession/getTokens/clearCredentials are jest.Mock (e.g. an intersection like AmplifyContext & { fetchAuthSession: jest.Mock; getTokens: jest.Mock; ... }), the casts disappear. A small convenience helper such as withTokens(ctx, accessToken) could also collapse the repeated mockResolvedValue({ tokens: ... }) setup. Not blocking — just a chance to reduce the boilerplate this migration introduces.
There was a problem hiding this comment.
Thanks — this is a good ergonomic improvement and I agree the as jest.Mock casts are noisy. I've deferred it from this PR for now, for a couple of reasons:
- Scope/risk — this PR is the B-auth split of v6 isolation improvements. #14786 and is meant to be a mechanical context migration plus the regression fix above. Changing the return type of
createMockAmplifyContext(e.g. toAmplifyContext & { fetchAuthSession: jest.Mock; getTokens: jest.Mock; clearCredentials: jest.Mock }) touches the shared test util that ~28 call sites depend on, and I'd rather not fold a broad test-ergonomics refactor into the same PR as a behavioral fix. - Consistency across splits — the same
createMockAmplifyContextutil is duplicated in the other B-splits (storage/analytics/notifications each get their own copy per the split plan). I'd prefer to make the typing change once, consistently, rather than diverge auth's copy here.
Happy to do it as a fast follow-up — either a tiny standalone PR against this util, or I can fold it in if you'd prefer it land together. Let me know your preference and I'll take care of it. The withTokens(ctx, accessToken) helper idea is nice too; I'll include that in the same follow-up.
- Restore USER_AUTH branch in signUpHelpers auto-sign-in: route directly to signInWithUserAuth(getGlobalContext(), input) instead of signIn(), which called resetAutoSignIn() and dropped the primed autoSignInStore session (regression). Re-add the dropped session assertion in autoSignIn.test.ts and correct autoSignInUserConfirmed.test.ts to assert the restored behavior. - Extract duplicated server context resolution into resolveServerContext shared util, used by server/getCurrentUser and server/fetchUserAttributes. - Add clearGlobalContext() cleanup in afterAll across test files that set a global context; make the Cognito ASF suite self-contained instead of relying on cross-describe context leakage.
Move @aws-amplify/core/internals/utils import before relative src imports to satisfy eslint import/order.
macos-latest runner's Xcode no longer ships the iPhone 16 simulator by default; target iPhone 17 so the xcodebuild test destination resolves.
| } | ||
|
|
||
| export async function assertUserNotAuthenticated() { | ||
| export async function assertUserNotAuthenticated(ctx: AmplifyContext) { |
There was a problem hiding this comment.
[major] The ctx threading added here is incomplete further down the call chain. getSignInResult (line 576 in this file), which every signIn variant invokes for challenge-to-output mapping, still reads Amplify.getConfig().Auth?.Cognito directly and has no ctx parameter:
export async function getSignInResult(params: { ... }) {
const authConfig = Amplify.getConfig().Auth?.Cognito; // singleton, not ctxThe concrete gap: a caller that passes signIn(customCtx, input) with a custom userPoolEndpoint will have their InitiateAuth call routed through the custom endpoint (via signInWithSRP(ctx, input) etc.), but if the flow reaches an MFA_SETUP challenge, the associateSoftwareToken call inside getSignInResult uses the singleton endpoint. Both calls happen in the same sign-in flow and may hit different endpoints.
The fix is to add ctx: AmplifyContext to getSignInResult's parameter object and thread it from each signIn variant. If this is deferred to a follow-up split, it is worth tracking explicitly so callers of the fn(ctx, input) overload are not silently getting mixed-context behavior.
There was a problem hiding this comment.
Good catch, fixed in 0c91982. You were right — getSignInResult was reading the singleton config, so a custom-endpoint ctx would route InitiateAuth correctly but the MFA_SETUP/associateSoftwareToken path through getSignInResult would hit the singleton endpoint.
Threaded ctx: AmplifyContext as the first param into getSignInResult and switched it to ctx.resourcesConfig.Auth?.Cognito. All 6 callers pass ctx (signInWithSRP/UserAuth/CustomAuth/CustomSRPAuth/UserPassword, confirmSignIn), and the internal WEB_AUTHN recursion (getSignInResult(ctx, result)) plus handleWebAuthnSignInResult were updated too — handleWebAuthnSignInResult now takes ctx as well and uses it for both its authConfig and dispatchSignedInHubEvent(ctx), so the whole challenge-mapping path is single-context now. No deferral needed.
| ): Promise<void>; | ||
| export async function signOut(...args: any[]): Promise<void> { | ||
| const [ctx, input] = resolveCtxArgs<[SignOutInput | undefined]>(args); | ||
| const cognitoConfig = ctx.resourcesConfig.Auth?.Cognito; |
There was a problem hiding this comment.
[major] ctx.resourcesConfig is used here for Cognito config, but the credentials and token cleanup later in this function still goes through module-level singletons. Specifically, in the non-OAuth branch:
tokenOrchestrator.clearTokens(); // singleton token store
await clearCredentials(); // clearCredentials imported from @aws-amplify/core, not ctx.clearCredentials()AmplifyContext exposes ctx.clearCredentials() for exactly this case. Calling the singleton clearCredentials() in a multi-context scenario (which the (ctx, input?) overload is intended for) clears the global Identity pool credential cache, not the per-request one. At minimum, clearCredentials() should be replaced with ctx.clearCredentials(). Whether tokenOrchestrator also needs to be context-scoped depends on this migration phase, but the gap should be explicit if it is a known deferral.
There was a problem hiding this comment.
Fixed in 0c91982. Replaced the singleton await clearCredentials() with await ctx.clearCredentials() in the non-OAuth branch and removed the now-unused clearCredentials import from @aws-amplify/core, so per-request credential state is cleared in the (ctx, input?) scenario.
On tokenOrchestrator.clearTokens() — I've left it as the module singleton for now, matching the reference v7-poc which also doesn't context-scope the token orchestrator in this phase. Flagging it explicitly as a known deferral: token-store context-scoping is a broader change beyond this B-auth split.
| signInInput?.options?.authFlowType === 'USER_AUTH' | ||
| ? await signInWithUserAuth(signInInput) | ||
| ? await signInWithUserAuth(getGlobalContext(), signInInput) | ||
| : await signIn(signInInput); |
There was a problem hiding this comment.
[minor] The two branches of handleAutoSignInWithCodeOrUserConfirmed pass context inconsistently:
- USER_AUTH path:
await signInWithUserAuth(getGlobalContext(), signInInput)-- context passed explicitly - all other paths (this line):
await signIn(signInInput)-- context resolved internally viaresolveCtxArgs
Both reach getGlobalContext() at runtime, so there is no functional difference. But the asymmetry is surprising to a reader and looks like an accidental omission. Aligning to await signIn(getGlobalContext(), signInInput) (or a short comment explaining the implicit resolution) would remove the ambiguity.
There was a problem hiding this comment.
Fixed in 0c91982. Aligned the else branch to await signIn(getGlobalContext(), signInInput) so both branches pass context explicitly. No functional change (as you noted, both resolve to the global context), just removes the surprising asymmetry.
| * Resolves a server-side argument that may be either the new {@link AmplifyContext} | ||
| * or a legacy {@link AmplifyServer.ContextSpec}, into a concrete `AmplifyContext`. | ||
| */ | ||
| export const resolveServerContext = ( |
There was a problem hiding this comment.
[minor] The duck-typing discriminator ('resourcesConfig' in ctxOrContextSpec) is the single point of backward compatibility between the new AmplifyContext path and the legacy ContextSpec path, but there are no dedicated unit tests for it.
Both branches are exercised only indirectly through server/getCurrentUser and server/fetchUserAttributes. A small focused test for resolveServerContext itself -- one call with a mock AmplifyContext (has resourcesConfig) and one with a mock ContextSpec (does not) -- would protect the discriminator independently, so a future change to either type fails here rather than silently in a higher-level test.
There was a problem hiding this comment.
Added in 0c91982: __tests__/providers/cognito/apis/server/resolveServerContext.test.ts. Two focused cases — one passing a branded AmplifyContext (asserts it's returned as-is and getAmplifyServerContext is not called), and one passing a legacy ContextSpec (asserts it resolves via getAmplifyServerContext(spec).amplify). So the discriminator is now protected independently of the higher-level server API tests.
| ? ctxOrContextSpec | ||
| : getAmplifyServerContext(ctxOrContextSpec).amplify; | ||
|
|
||
| // The `'resourcesConfig' in x` duck-type does not narrow the union to |
There was a problem hiding this comment.
[nit] This three-line block restates the TypeScript limitation in more words than the cast it documents. A single line captures the same information:
// `'resourcesConfig' in x` doesn't narrow the union; AmplifyClass satisfies AmplifyContext structurally.
return ctx as AmplifyContext;There was a problem hiding this comment.
Done in 0c91982 — collapsed to a single line: // 'resourcesConfig' in x doesn't narrow the union; AmplifyClass satisfies AmplifyContext structurally.
- Thread ctx:AmplifyContext through getSignInResult and handleWebAuthnSignInResult (incl. WEB_AUTHN recursion) so the MFA_SETUP/TOTP associateSoftwareToken call uses the same context as the rest of the sign-in flow instead of the global singleton config. Updated all 6 callers to pass ctx. - signOut: use ctx.clearCredentials() instead of the singleton in the non-OAuth branch so per-request credential state is cleared. - signUpHelpers: pass getGlobalContext() explicitly in the non-USER_AUTH auto-sign-in branch for symmetry with the USER_AUTH branch. - Add focused unit test for resolveServerContext covering both the AmplifyContext and legacy ContextSpec branches. - Collapse verbose comment in resolveServerContext to one line.
* feat(auth): migrate auth APIs to AmplifyContext (B-auth split)
- Add AmplifyContext overloads to all public auth APIs (signIn, signUp,
signOut, getCurrentUser, fetchUserAttributes, confirmSignIn, etc.)
- Public APIs use resolveCtxArgs with getGlobalContext() fallback
- Server wrappers (server/getCurrentUser, server/fetchUserAttributes)
take AmplifyContext explicitly — no global fallback
- Internal signIn variants take (ctx, input) directly
- Utilities (assertUserNotAuthenticated, dispatchSignedInHubEvent) accept ctx
- Replace Amplify.getConfig() with ctx.resourcesConfig throughout
- Replace AmplifyClassV6 with AmplifyContext in internal APIs
- Add createMockAmplifyContext test utility
- Update affected test files to use mock context
* fix: use resolveCtxArgs<[]> for no-input overloads
resolveCtxArgs generic constraint requires T extends unknown[].
undefined does not satisfy this - use empty tuple [] instead.
* fix: use ctx.fetchAuthSession() instead of singleton fetchAuthSession()
The fetchAuthSession helper from core/internals/utils expects AmplifyClass,
not AmplifyContext. Use the context's own fetchAuthSession method directly.
* fix: server wrappers accept both AmplifyContext and ContextSpec
Maintain backward compatibility with adapter-nextjs which still uses
runWithAmplifyServerContext + ContextSpec pattern. Server wrappers now
detect whether they received an AmplifyContext or ContextSpec and
resolve accordingly.
* fix: resolve lint and formatting issues
- Remove unused Amplify imports from test files
- Fix prettier formatting (line length, indentation)
* fix: remove tsconfig.tsbuildinfo build artifact
* fix: update auth tests to use AmplifyContext directly
Migrate test mocking from Amplify.getConfig() singleton to passing
mockCtx directly via createMockAmplifyContext(). This aligns tests
with the new resolveCtxArgs pattern where APIs accept an optional
AmplifyContext as their first argument.
- Remove jest.mock('@aws-amplify/core') in favor of direct ctx passing
- Replace fetchAuthSession singleton mock with ctx.fetchAuthSession
- Use customCtx for endpoint override tests
- Fix autoSignInUserConfirmed to match updated signUpHelpers routing
- Add Amplify.configure() for tests that reach getSignInResult (still
uses singleton internally)
* fix(auth): address PR review comments
- Restore USER_AUTH branch in signUpHelpers auto-sign-in: route directly
to signInWithUserAuth(getGlobalContext(), input) instead of signIn(),
which called resetAutoSignIn() and dropped the primed autoSignInStore
session (regression). Re-add the dropped session assertion in
autoSignIn.test.ts and correct autoSignInUserConfirmed.test.ts to
assert the restored behavior.
- Extract duplicated server context resolution into resolveServerContext
shared util, used by server/getCurrentUser and server/fetchUserAttributes.
- Add clearGlobalContext() cleanup in afterAll across test files that set
a global context; make the Cognito ASF suite self-contained instead of
relying on cross-describe context leakage.
* fix(auth): correct import order in autoSignInUserConfirmed test
Move @aws-amplify/core/internals/utils import before relative src imports
to satisfy eslint import/order.
* test(rtn-passkeys): use iPhone 17 simulator for iOS unit tests
macos-latest runner's Xcode no longer ships the iPhone 16 simulator by
default; target iPhone 17 so the xcodebuild test destination resolves.
* fix(auth): address review feedback on context threading
- Thread ctx:AmplifyContext through getSignInResult and
handleWebAuthnSignInResult (incl. WEB_AUTHN recursion) so the
MFA_SETUP/TOTP associateSoftwareToken call uses the same context as
the rest of the sign-in flow instead of the global singleton config.
Updated all 6 callers to pass ctx.
- signOut: use ctx.clearCredentials() instead of the singleton in the
non-OAuth branch so per-request credential state is cleared.
- signUpHelpers: pass getGlobalContext() explicitly in the non-USER_AUTH
auto-sign-in branch for symmetry with the USER_AUTH branch.
- Add focused unit test for resolveServerContext covering both the
AmplifyContext and legacy ContextSpec branches.
- Collapse verbose comment in resolveServerContext to one line.
* feat(auth): migrate auth APIs to AmplifyContext (B-auth split)
- Add AmplifyContext overloads to all public auth APIs (signIn, signUp,
signOut, getCurrentUser, fetchUserAttributes, confirmSignIn, etc.)
- Public APIs use resolveCtxArgs with getGlobalContext() fallback
- Server wrappers (server/getCurrentUser, server/fetchUserAttributes)
take AmplifyContext explicitly — no global fallback
- Internal signIn variants take (ctx, input) directly
- Utilities (assertUserNotAuthenticated, dispatchSignedInHubEvent) accept ctx
- Replace Amplify.getConfig() with ctx.resourcesConfig throughout
- Replace AmplifyClassV6 with AmplifyContext in internal APIs
- Add createMockAmplifyContext test utility
- Update affected test files to use mock context
* fix: use resolveCtxArgs<[]> for no-input overloads
resolveCtxArgs generic constraint requires T extends unknown[].
undefined does not satisfy this - use empty tuple [] instead.
* fix: use ctx.fetchAuthSession() instead of singleton fetchAuthSession()
The fetchAuthSession helper from core/internals/utils expects AmplifyClass,
not AmplifyContext. Use the context's own fetchAuthSession method directly.
* fix: server wrappers accept both AmplifyContext and ContextSpec
Maintain backward compatibility with adapter-nextjs which still uses
runWithAmplifyServerContext + ContextSpec pattern. Server wrappers now
detect whether they received an AmplifyContext or ContextSpec and
resolve accordingly.
* fix: resolve lint and formatting issues
- Remove unused Amplify imports from test files
- Fix prettier formatting (line length, indentation)
* fix: remove tsconfig.tsbuildinfo build artifact
* fix: update auth tests to use AmplifyContext directly
Migrate test mocking from Amplify.getConfig() singleton to passing
mockCtx directly via createMockAmplifyContext(). This aligns tests
with the new resolveCtxArgs pattern where APIs accept an optional
AmplifyContext as their first argument.
- Remove jest.mock('@aws-amplify/core') in favor of direct ctx passing
- Replace fetchAuthSession singleton mock with ctx.fetchAuthSession
- Use customCtx for endpoint override tests
- Fix autoSignInUserConfirmed to match updated signUpHelpers routing
- Add Amplify.configure() for tests that reach getSignInResult (still
uses singleton internally)
* fix(auth): address PR review comments
- Restore USER_AUTH branch in signUpHelpers auto-sign-in: route directly
to signInWithUserAuth(getGlobalContext(), input) instead of signIn(),
which called resetAutoSignIn() and dropped the primed autoSignInStore
session (regression). Re-add the dropped session assertion in
autoSignIn.test.ts and correct autoSignInUserConfirmed.test.ts to
assert the restored behavior.
- Extract duplicated server context resolution into resolveServerContext
shared util, used by server/getCurrentUser and server/fetchUserAttributes.
- Add clearGlobalContext() cleanup in afterAll across test files that set
a global context; make the Cognito ASF suite self-contained instead of
relying on cross-describe context leakage.
* fix(auth): correct import order in autoSignInUserConfirmed test
Move @aws-amplify/core/internals/utils import before relative src imports
to satisfy eslint import/order.
* test(rtn-passkeys): use iPhone 17 simulator for iOS unit tests
macos-latest runner's Xcode no longer ships the iPhone 16 simulator by
default; target iPhone 17 so the xcodebuild test destination resolves.
* fix(auth): address review feedback on context threading
- Thread ctx:AmplifyContext through getSignInResult and
handleWebAuthnSignInResult (incl. WEB_AUTHN recursion) so the
MFA_SETUP/TOTP associateSoftwareToken call uses the same context as
the rest of the sign-in flow instead of the global singleton config.
Updated all 6 callers to pass ctx.
- signOut: use ctx.clearCredentials() instead of the singleton in the
non-OAuth branch so per-request credential state is cleared.
- signUpHelpers: pass getGlobalContext() explicitly in the non-USER_AUTH
auto-sign-in branch for symmetry with the USER_AUTH branch.
- Add focused unit test for resolveServerContext covering both the
AmplifyContext and legacy ContextSpec branches.
- Collapse verbose comment in resolveServerContext to one line.
Thread AmplifyContext explicitly through the storage package instead of relying on the global Amplify singleton, mirroring the landed auth migration (#14836). - Public S3 APIs (copy, downloadData, getProperties, getUrl, list, remove, uploadData) gain (ctx, input) overloads with a global fallback via resolveCtxArgs - Internal workers, resolveS3ConfigAndInput, and access-grant internals take ctx: AmplifyContext; config via ctx.resourcesConfig and auth via ctx.fetchAuthSession - Server wrappers accept AmplifyContext | AmplifyServer.ContextSpec via new resolveServerContext, preserving adapter-nextjs compatibility - Tests migrated to a branded mock AmplifyContext (createMockAmplifyContext) Excludes the endpoint-provider feature (depends on unlanded core Storage types) and does not delete server impls (adapter-nextjs split not yet landed).
Summary
Migrates all auth package APIs from the legacy
Amplifysingleton pattern to the newAmplifyContextinterface.Changes
Public APIs (26 files)
All exported auth functions now have overloads:
fn(input)— usesgetGlobalContext()fallback (browser/client usage)fn(ctx, input)— explicit context (server or multi-context usage)Uses
resolveCtxArgsfrom core to resolve the optional leading context argument.Server wrappers (2 files)
server/getCurrentUser.tsandserver/fetchUserAttributes.tstakeAmplifyContextexplicitlyserver/entry point structure (like storage package)Internal functions (5 signIn variants + utilities)
signInWithSRP,signInWithUserPassword, etc. take(ctx, input)directlyassertUserNotAuthenticated(ctx),dispatchSignedInHubEvent(ctx)Foundation changes
AmplifyClassV6→AmplifyContextamplify.getConfig()→amplify.resourcesConfigamplify.Auth.getTokens()→amplify.getTokens()Tests
createMockAmplifyContext()test utilityWhat was tested